package com.cheetah.server.bootstrap;

import com.cheetah.config.ServerConfig;
import com.cheetah.handler.NettyHandlerInitializer;
import com.cheetah.server.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;

@Component
@Slf4j
public class CheetahServerBootstrap implements Bootstrap {

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private NettyHandlerInitializer nettyHandlerInitializer;

    EventLoopGroup bossGroup;
    EventLoopGroup workerGroup;

    public void start() {
        log.info("tcp server now starting...");
        bossGroup = new NioEventLoopGroup(serverConfig.getBoss());
        workerGroup = new NioEventLoopGroup(serverConfig.getWorker());
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup,workerGroup)
                .channel(NioServerSocketChannel.class)
                //.option(ChannelOption.SO_KEEPALIVE, serverConfig.isKeepAlive())
                .option(ChannelOption.SO_BACKLOG, serverConfig.getBacklog())
                //.option(ChannelOption.SO_TIMEOUT, serverConfig.getTimeout())
                //.option(ChannelOption.TCP_NODELAY, serverConfig.isTcpNoDelay())
                .childHandler(nettyHandlerInitializer);

//        new ChannelInitializer<SocketChannel>(){
//
//            @Override
//            protected void initChannel(SocketChannel ch) throws Exception {
//                ch.pipeline()
//                        .addLast("timeout", new ReadTimeoutHandler(serverConfig.getReadTimeout()))
//                ;
//            }
//        }
        try {
            ChannelFuture f = b.bind(serverConfig.getPort()).sync();
            log.info("server started on port {}!",serverConfig.getPort());
            f.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            log.error(e.getMessage(),e);
        } finally{
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }

    @PreDestroy
    public void stop(){
        if(bossGroup != null && workerGroup != null){
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
